package com.appspot.aliga.openligadb;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.LocalDateTime;

import com.appspot.aliga.League;
import com.appspot.aliga.persistence.LeagueTableEntry;
import com.appspot.aliga.persistence.Match;
import com.appspot.aliga.persistence.PersistenceService;

public class LeagueTableUpdater {

	private static final int TEAM1 = 1;
	private static final int TEAM2 = 2;

	private static final LeagueEntryComperator LEC = new LeagueEntryComperator();
	
	public void updateAllLeagueTable() {
		for (League league : League.values()) {
			this.updateForLeague(league);
		}
	}

	public void updateForLeague(League league) {
		LocalDateTime now = new LocalDateTime();
		PersistenceService service = new PersistenceService();
		List<Match> matches = service.findMatches(league.getId());

		Map<String, LeagueTableEntry> leagueTable = new HashMap<String, LeagueTableEntry>();

		for (Match match : matches) {

			if (match.getMatchDate() != null) {
				LocalDateTime matchDate = new LocalDateTime(match
						.getMatchDate(), DateTimeZone.UTC);
				if (matchDate.isAfter(now)) {
					// match is in the future
					continue;
				}
			} else {
				continue;
			}

			addResult(leagueTable, league, match.getTeam1Name(), match
					.getTeam1Result(), match.getTeam2Result(), getPoints(match,
					TEAM1));
			addResult(leagueTable, league, match.getTeam2Name(), match
					.getTeam2Result(), match.getTeam1Result(), getPoints(match,
					TEAM2));
		}

		List<LeagueTableEntry> entries = new ArrayList<LeagueTableEntry>(
				leagueTable.values());
		Collections.sort(entries, LEC);

		for (int i = 0; i < entries.size(); i++) {
			LeagueTableEntry le = entries.get(i);
			if (i == 0) {
				le.setPosition(i + 1);
				continue;
			}

			LeagueTableEntry prevLe = entries.get(i - 1);
			if (LEC.compare(le, prevLe) == 0) {
				le.setPosition(prevLe.getPosition());
			} else {
				le.setPosition(i + 1);
			}
		}

		service.saveLeagueTableForLeague(league, entries);
	}

	private void addResult(Map<String, LeagueTableEntry> leagueTable,
			League league, String teamName, int goalsScored, int goalsReceived,
			int points) {
		LeagueTableEntry entry = leagueTable.get(teamName);
		if (entry == null) {
			entry = new LeagueTableEntry();
			entry.setLeagueID(league.getId());
			entry.setTeamName(teamName);
		}

		entry.setGamesPlayed(entry.getGamesPlayed() + 1);
		if (points == 3) {
			entry.setWins(entry.getWins() + 1);
		} else if (points == 0) {
			entry.setLosses(entry.getLosses() + 1);
		} else if (points == 1) {
			entry.setTies(entry.getTies() + 1);
		}
		entry.addPoints(points);
		entry.addResult(goalsScored, goalsReceived);

		leagueTable.put(teamName, entry);

	}

	private int getPoints(Match match, int team) {
		// Unentschieden
		if (match.getTeam1Result() == match.getTeam2Result()) {
			return 1;
		}

		if (team == TEAM1) {
			if (match.getTeam1Result() > match.getTeam2Result()) {
				return 3;
			}
			return 0;
		}
		if (team == TEAM2) {
			if (match.getTeam2Result() > match.getTeam1Result()) {
				return 3;
			}
			return 0;
		}
		return 0;
	}

	
}
